package org.manager.authorize;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.manager.units.SysUnits;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository("authorizeRepository")
public class AuthorizeRepositoryImpl implements AuthorizeRepository {

	@Resource(name="hibernateTemplate")
	private HibernateTemplate htmp;
	
	@SuppressWarnings("unchecked")
	public Set<UserAccount> findUserByUnit(final Serializable unitId) {
		return (Set<UserAccount>)htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				SysUnits unit = (SysUnits)session.load(SysUnits.class, unitId);
				Hibernate.initialize(unit.getUserSet());
				return unit.getUserSet();
			}
		});
	}
	
	@Override
	public void addUserAccount(final UserAccount user) {
		htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				SysUnits unit = (SysUnits)session.load(SysUnits.class, user.getGroupId());
				unit.addUser(user);
				session.save(user);
				return null;
			}
		});
	}
	
	@Override
	public UserAccount loadUser(Serializable userId) {
		return (UserAccount)htmp.get(UserAccount.class, userId);
	}
	
	@Override
	public void modifyUser(UserAccount user) {
		htmp.update(user);
	}
	
	@Override
	public int batchDeleteUserAccount(final Serializable userId[]) {
		return (Integer)htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				if(userId != null && userId.length > 0){
					SysUnits unit = (SysUnits)session.get(SysUnits.class, ((UserAccount)session.load(UserAccount.class, userId[0])).getGroupId());
					if(unit != null){
						for(int i=0; i<userId.length; i++){
							//REFACTOR
							UserAccount user = (UserAccount)session.load(UserAccount.class, userId[i]);
							user.getRoleSet().clear();
							unit.getUserSet().remove(user);
							session.delete(user);
						}
					}
					/*for(int i=0; i<userId.length; i++){
						session.delete(session.load(UserAccount.class, userId[i]));
					}*/
				}
				return userId.length;
			}
		});
	}
	
	//============ Role ==============
	
	@SuppressWarnings("unchecked")
	@Override
	public List<SystemRole> getAllRole() {
		return htmp.loadAll(SystemRole.class);
	}
	
	@Override
	public Serializable addRole(SystemRole role) {
		return htmp.save(role);
	}
	
	@Override
	public SystemRole loadRoleById(Serializable roleId) {
		return (SystemRole)htmp.get(SystemRole.class, roleId);
	}
	
	@Override
	public void batchDeleteRoleById(String roleId[]) {
		for(String id : roleId){
			htmp.delete(htmp.load(SystemRole.class, id));
		}
	}
	
	@Override
	public void modifyRole(SystemRole role) {
		htmp.update(role);
	}
	
	@Override
	public void authorizeRole(final String[] accountIds, final String[] roleIds) {
		htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				for(String aid : accountIds){
					UserAccount user = (UserAccount)session.load(UserAccount.class, aid);
					if(accountIds.length == 1){	//如果是维护单个账户的角色信息.
						user.getRoleSet().clear();
					}
					
					if(roleIds != null && roleIds.length > 0){
						for(String rolId : roleIds){
							if(StringUtils.isNotBlank(rolId))
							user.getRoleSet().add((SystemRole)session.load(SystemRole.class, rolId));
						}
					}
				}//
				return null;
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<SystemRole> getAccountsRoles(final String accountId) {
		return (List<SystemRole>)htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				List<SystemRole> roleList = new ArrayList<SystemRole>();
				UserAccount user = (UserAccount)session.load(UserAccount.class, accountId);
				Iterator it = session.createQuery("From SystemRole").iterate();
				while(it.hasNext()){
					SystemRole rcopy = new SystemRole();
					try {
						BeanUtils.copyProperties(rcopy, (SystemRole)it.next());
					} catch (Exception e) {
						e.printStackTrace();
					} 
					if(user.getRoleSet().contains(rcopy)){
						rcopy.setChecked(true);
					}
					roleList.add(rcopy);
				}
				user = null;
				it = null;
				return roleList;
			}
		});
	}
	
	@Override
	public void roleAuthority(final List<Function> funList, final String[] roleArray) {
		htmp.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				for(String roleId : roleArray){
					SystemRole role = (SystemRole)session.load(SystemRole.class, roleId);
					role.getFunctionSet().clear();
					for(Function fun : funList){
						if(fun.hasFunctonChecked()){
							fun.setRoleId(roleId);
							session.save(fun);
							role.addFunction(fun);
							//Menu m = (Menu)session.load(Menu.class, fun.getMenuId());
							//m.addFunction(fun);
						}//
					}//for
				}//for
				return null;
			}
		});
	}

}
